<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>发布/订阅模式</title>
  </head>

  <body>
    <script>
      //定义一家猎人工会
      //主要功能包括任务发布大厅(topics)，以及订阅任务(subscribe)，发布任务(publish)

      // 定义中间件（这里的发布大厅扮演了中间件这样的一个角色）
      var HunterUnion = {
        type: "hunt",
        topics: Object.create(null),
        subscribe: function (topic, fn) {
          if (!this.topics[topic]) {
            this.topics[topic] = [];
          }
          this.topics[topic].push(fn);
        },
        publish: function (topic, money) {
          if (!this.topics[topic]) return;
          for (var fn of this.topics[topic]) {
            fn(money);
          }
        },
      };

      //定义一个猎人类
      //包括姓名，级别
      function Hunter(name, level) {
        this.name = name;
        this.level = level;
      }

      //猎人可在猎人工会订阅任务
      Hunter.prototype.subscribe = function (topic, fn) {
        console.log(
          this.level + "猎人" + this.name + "订阅了狩猎" + topic + "的任务"
        );
        HunterUnion.subscribe(topic, fn);
      };
      //猎人可在猎人工会发布任务
      Hunter.prototype.publish = function (topic, money) {
        console.log(
          this.level + "猎人" + this.name + "发布了狩猎" + topic + "的任务"
        );
        HunterUnion.publish(topic, money);
      };

      //创建猎人
      var hunterMing = new Hunter("小明", "黄金");
      var hunterJin = new Hunter("小金", "白银");
      var hunterZhang = new Hunter("小张", "黄金");
      var hunterPeter = new Hunter("Peter", "青铜");

      //小明，小金，小张分别订阅了狩猎tiger的任务
      hunterMing.subscribe("tiger", function (money) {
        console.log("小明表示：" + (money > 200 ? "" : "不") + "接取任务");
      });
      hunterJin.subscribe("tiger", function (money) {
        console.log("小金表示：接取任务");
      });
      hunterZhang.subscribe("tiger", function (money) {
        console.log("小张表示：接取任务");
      });
      //Peter订阅了狩猎sheep的任务
      hunterPeter.subscribe("sheep", function (money) {
        console.log("Peter表示：接取任务");
      });

      //Peter发布了狩猎tiger的任务
      hunterPeter.publish("tiger", 190);
      //hunterJin发布了狩猎sheep的任务
      hunterJin.publish("sheep", 500);

      //猎人们发布(发布者)或订阅(观察者/订阅者)任务都是通过猎人工会(调度中心)关联起来的，他们没有直接的交流。
    </script>
  </body>
</html>
